<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebSocket 测试页面</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: rgba(255, 255, 255, 0.95);
            border-radius: 15px;
            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
            overflow: hidden;
        }

        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }

        .header h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
        }

        .header p {
            font-size: 1.1em;
            opacity: 0.9;
        }

        .main-content {
            padding: 30px;
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 30px;
        }

        .control-panel, .message-panel {
            background: #f8f9fa;
            border-radius: 10px;
            padding: 25px;
            border: 1px solid #e9ecef;
        }

        .section-title {
            font-size: 1.4em;
            font-weight: 600;
            color: #333;
            margin-bottom: 20px;
            padding-bottom: 10px;
            border-bottom: 2px solid #667eea;
        }

        .connection-status {
            padding: 15px;
            border-radius: 8px;
            margin-bottom: 20px;
            text-align: center;
            font-weight: 600;
            transition: all 0.3s ease;
        }

        .status-disconnected {
            background: #ffebee;
            color: #c62828;
            border: 1px solid #ffcdd2;
        }

        .status-connecting {
            background: #fff3e0;
            color: #ef6c00;
            border: 1px solid #ffcc02;
        }

        .status-connected {
            background: #e8f5e8;
            color: #2e7d32;
            border: 1px solid #c8e6c9;
        }

        .input-group {
            margin-bottom: 20px;
        }

        .input-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #555;
        }

        .input-group input, .input-group select, .input-group textarea {
            width: 100%;
            padding: 12px;
            border: 2px solid #e0e0e0;
            border-radius: 8px;
            font-size: 14px;
            transition: border-color 0.3s ease;
        }

        .input-group input:focus, .input-group select:focus, .input-group textarea:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
        }

        .btn {
            padding: 12px 24px;
            border: none;
            border-radius: 8px;
            font-size: 14px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }

        .btn-primary {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }

        .btn-primary:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
        }

        .btn-success {
            background: linear-gradient(135deg, #56ab2f 0%, #a8e6cf 100%);
            color: white;
        }

        .btn-success:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 25px rgba(86, 171, 47, 0.3);
        }

        .btn-danger {
            background: linear-gradient(135deg, #ff416c 0%, #ff4b2b 100%);
            color: white;
        }

        .btn-danger:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 25px rgba(255, 65, 108, 0.3);
        }

        .btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
            transform: none !important;
            box-shadow: none !important;
        }

        .message-log {
            background: #2d3748;
            color: #e2e8f0;
            border-radius: 8px;
            padding: 20px;
            max-height: 400px;
            overflow-y: auto;
            font-family: 'Courier New', monospace;
            font-size: 13px;
            line-height: 1.6;
        }

        .message-item {
            margin-bottom: 10px;
            padding: 8px 12px;
            border-radius: 6px;
            word-wrap: break-word;
        }

        .message-sent {
            background: rgba(102, 126, 234, 0.2);
            border-left: 4px solid #667eea;
        }

        .message-received {
            background: rgba(72, 187, 120, 0.2);
            border-left: 4px solid #48bb78;
        }

        .message-error {
            background: rgba(245, 101, 101, 0.2);
            border-left: 4px solid #f56565;
        }

        .message-info {
            background: rgba(66, 153, 225, 0.2);
            border-left: 4px solid #4299e1;
        }

        .timestamp {
            font-size: 11px;
            opacity: 0.7;
            margin-right: 10px;
        }

        .button-group {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
        }

        .button-group .btn {
            flex: 1;
        }

        .quick-actions {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 10px;
            margin-top: 20px;
        }

        .stats {
            display: flex;
            justify-content: space-between;
            background: #f8f9fa;
            padding: 15px;
            border-radius: 8px;
            margin-bottom: 20px;
            border: 1px solid #e9ecef;
        }

        .stat-item {
            text-align: center;
        }

        .stat-value {
            font-size: 1.5em;
            font-weight: 700;
            color: #667eea;
        }

        .stat-label {
            font-size: 0.9em;
            color: #666;
            margin-top: 5px;
        }

        @media (max-width: 768px) {
            .main-content {
                grid-template-columns: 1fr;
                gap: 20px;
            }
            
            .header h1 {
                font-size: 2em;
            }
            
            .button-group {
                flex-direction: column;
            }
            
            .quick-actions {
                grid-template-columns: 1fr;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🚀 WebSocket 测试工具</h1>
            <p>测试 WebSocket 连接、消息发送和实时通信功能</p>
        </div>

        <div class="main-content">
            <!-- 控制面板 -->
            <div class="control-panel">
                <h2 class="section-title">🎛️ 连接控制</h2>
                
                <div id="connectionStatus" class="connection-status status-disconnected">
                    🔴 未连接
                </div>

                <div class="stats">
                    <div class="stat-item">
                        <div id="sentCount" class="stat-value">0</div>
                        <div class="stat-label">已发送</div>
                    </div>
                    <div class="stat-item">
                        <div id="receivedCount" class="stat-value">0</div>
                        <div class="stat-label">已接收</div>
                    </div>
                    <div class="stat-item">
                        <div id="connectionTime" class="stat-value">--</div>
                        <div class="stat-label">连接时长</div>
                    </div>
                </div>

                <div class="input-group">
                    <label for="wsUrl">WebSocket URL:</label>
                    <input type="text" id="wsUrl" value="ws://localhost:8084/ws/connect?user_id=test_user&role=user" placeholder="输入WebSocket服务器地址">
                </div>

                <div class="button-group">
                    <button id="connectBtn" class="btn btn-success">🔗 连接</button>
                    <button id="disconnectBtn" class="btn btn-danger" disabled>❌ 断开</button>
                </div>

                <div class="input-group">
                    <label for="messageType">消息类型:</label>
                    <select id="messageType">
                        <option value="text">文本消息</option>
                        <option value="ping">心跳测试</option>
                        <option value="broadcast_test">广播测试</option>
                        <option value="join_room:test">加入房间</option>
                    </select>
                </div>

                <div class="input-group">
                    <label for="messageContent">消息内容:</label>
                    <textarea id="messageContent" rows="3" placeholder="输入要发送的消息内容"></textarea>
                </div>

                <button id="sendBtn" class="btn btn-primary" disabled>📤 发送消息</button>

                <div class="quick-actions">
                    <button class="btn btn-primary" onclick="sendQuickMessage('ping')">💓 心跳</button>
                    <button class="btn btn-primary" onclick="sendQuickMessage('broadcast_test')">📡 广播</button>
                    <button class="btn btn-primary" onclick="sendQuickMessage('join_room:test')">🏠 加入房间</button>
                    <button class="btn btn-danger" onclick="clearMessages()">🗑️ 清空日志</button>
                </div>
            </div>

            <!-- 消息面板 -->
            <div class="message-panel">
                <h2 class="section-title">💬 消息日志</h2>
                <div id="messageLog" class="message-log">
                    <div class="message-item message-info">
                        <span class="timestamp">[系统]</span>
                        📝 WebSocket 测试工具已准备就绪，请点击"连接"按钮开始测试
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        // 全局变量
        let ws = null;
        let isConnected = false;
        let sentCount = 0;
        let receivedCount = 0;
        let connectTime = null;
        let connectionTimer = null;

        // DOM 元素
        const connectBtn = document.getElementById('connectBtn');
        const disconnectBtn = document.getElementById('disconnectBtn');
        const sendBtn = document.getElementById('sendBtn');
        const wsUrlInput = document.getElementById('wsUrl');
        const messageTypeSelect = document.getElementById('messageType');
        const messageContentTextarea = document.getElementById('messageContent');
        const messageLog = document.getElementById('messageLog');
        const connectionStatus = document.getElementById('connectionStatus');
        const sentCountElement = document.getElementById('sentCount');
        const receivedCountElement = document.getElementById('receivedCount');
        const connectionTimeElement = document.getElementById('connectionTime');

        // 事件监听器
        connectBtn.addEventListener('click', connectWebSocket);
        disconnectBtn.addEventListener('click', disconnectWebSocket);
        sendBtn.addEventListener('click', sendMessage);
        messageTypeSelect.addEventListener('change', updateMessageContent);

        // 连接 WebSocket
        function connectWebSocket() {
            const url = wsUrlInput.value.trim();
            if (!url) {
                addMessage('❌ 请输入有效的WebSocket URL', 'error');
                return;
            }

            addMessage(`🔄 正在连接到: ${url}`, 'info');
            updateConnectionStatus('connecting', '🟡 连接中...');

            try {
                ws = new WebSocket(url);

                ws.onopen = function(event) {
                    isConnected = true;
                    connectTime = new Date();
                    updateConnectionStatus('connected', '🟢 已连接');
                    connectBtn.disabled = true;
                    disconnectBtn.disabled = false;
                    sendBtn.disabled = false;
                    addMessage('✅ WebSocket 连接成功建立', 'info');
                    startConnectionTimer();
                };

                ws.onmessage = function(event) {
                    receivedCount++;
                    updateStats();
                    let messageData;
                    try {
                        messageData = JSON.parse(event.data);
                        addMessage(`📥 收到消息: ${JSON.stringify(messageData, null, 2)}`, 'received');
                    } catch (e) {
                        addMessage(`📥 收到消息: ${event.data}`, 'received');
                    }
                };

                ws.onclose = function(event) {
                    isConnected = false;
                    updateConnectionStatus('disconnected', '🔴 未连接');
                    connectBtn.disabled = false;
                    disconnectBtn.disabled = true;
                    sendBtn.disabled = true;
                    stopConnectionTimer();
                    
                    if (event.wasClean) {
                        addMessage(`🔌 连接已正常关闭 (代码: ${event.code})`, 'info');
                    } else {
                        addMessage(`❌ 连接意外断开 (代码: ${event.code}, 原因: ${event.reason || '未知'})`, 'error');
                    }
                };

                ws.onerror = function(error) {
                    addMessage(`💥 WebSocket 错误: ${error.message || '连接失败'}`, 'error');
                    updateConnectionStatus('disconnected', '🔴 连接失败');
                };

            } catch (error) {
                addMessage(`❌ 创建WebSocket连接失败: ${error.message}`, 'error');
                updateConnectionStatus('disconnected', '🔴 连接失败');
            }
        }

        // 断开 WebSocket
        function disconnectWebSocket() {
            if (ws && isConnected) {
                ws.close(1000, '用户主动断开连接');
                addMessage('👋 用户主动断开连接', 'info');
            }
        }

        // 发送消息
        function sendMessage() {
            if (!ws || !isConnected) {
                addMessage('❌ 请先建立WebSocket连接', 'error');
                return;
            }

            const messageType = messageTypeSelect.value;
            let messageContent = messageContentTextarea.value.trim();

            // 如果是预定义类型且没有自定义内容，使用默认消息
            if (!messageContent) {
                messageContent = messageType;
            }

            try {
                ws.send(messageContent);
                sentCount++;
                updateStats();
                addMessage(`📤 发送消息: ${messageContent}`, 'sent');
                messageContentTextarea.value = '';
            } catch (error) {
                addMessage(`❌ 发送消息失败: ${error.message}`, 'error');
            }
        }

        // 发送快速消息
        function sendQuickMessage(message) {
            if (!ws || !isConnected) {
                addMessage('❌ 请先建立WebSocket连接', 'error');
                return;
            }

            try {
                ws.send(message);
                sentCount++;
                updateStats();
                addMessage(`📤 发送快速消息: ${message}`, 'sent');
            } catch (error) {
                addMessage(`❌ 发送快速消息失败: ${error.message}`, 'error');
            }
        }

        // 清空消息日志
        function clearMessages() {
            messageLog.innerHTML = '<div class="message-item message-info"><span class="timestamp">[系统]</span>📝 消息日志已清空</div>';
            sentCount = 0;
            receivedCount = 0;
            updateStats();
        }

        // 添加消息到日志
        function addMessage(message, type) {
            const timestamp = new Date().toLocaleTimeString();
            const messageElement = document.createElement('div');
            messageElement.className = `message-item message-${type}`;
            messageElement.innerHTML = `<span class="timestamp">[${timestamp}]</span>${message}`;
            
            messageLog.appendChild(messageElement);
            messageLog.scrollTop = messageLog.scrollHeight;
        }

        // 更新连接状态
        function updateConnectionStatus(status, text) {
            connectionStatus.className = `connection-status status-${status}`;
            connectionStatus.textContent = text;
        }

        // 更新统计信息
        function updateStats() {
            sentCountElement.textContent = sentCount;
            receivedCountElement.textContent = receivedCount;
        }

        // 开始连接计时器
        function startConnectionTimer() {
            connectionTimer = setInterval(() => {
                if (connectTime) {
                    const duration = Math.floor((new Date() - connectTime) / 1000);
                    const minutes = Math.floor(duration / 60);
                    const seconds = duration % 60;
                    connectionTimeElement.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
                }
            }, 1000);
        }

        // 停止连接计时器
        function stopConnectionTimer() {
            if (connectionTimer) {
                clearInterval(connectionTimer);
                connectionTimer = null;
            }
            connectionTimeElement.textContent = '--';
        }

        // 根据消息类型更新内容提示
        function updateMessageContent() {
            const messageType = messageTypeSelect.value;
            const placeholders = {
                'text': '输入自定义文本消息...',
                'ping': '发送心跳检测消息',
                'broadcast_test': '发送广播测试消息',
                'join_room:test': '加入测试房间'
            };
            
            messageContentTextarea.placeholder = placeholders[messageType] || '输入消息内容...';
        }

        // 页面加载完成时的初始化
        document.addEventListener('DOMContentLoaded', function() {
            addMessage('🚀 页面加载完成，WebSocket测试工具已就绪', 'info');
            updateStats();
        });

        // 页面卸载时自动断开连接
        window.addEventListener('beforeunload', function() {
            if (ws && isConnected) {
                ws.close(1001, '页面即将关闭');
            }
        });
    </script>
</body>
</html>